home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1997 April / EnigmA AMIGA RUN 17 (1997)(G.R. Edizioni)(IT)[!][issue 1997-04][EAR-CD].iso / EARCD / comm / bbs / Hydra11s.lha / HBBS / Source / Node / Node_Serial.c < prev    next >
C/C++ Source or Header  |  1996-10-31  |  9KB  |  361 lines

  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <stdlib.h>
  4. #include <ctype.h>
  5.  
  6. #include <exec/exec.h>
  7. #include <dos/dos.h>
  8.  
  9. #include <devices/serial.h>
  10. #include <hardware/cia.h>
  11.  
  12. #include <clib/exec_protos.h>
  13. #include <clib/alib_protos.h>
  14. #include <clib/dos_protos.h>
  15.  
  16. #define NOTMAIN
  17.  
  18. #define ClrSignal(s)  SetSignal(0,s)
  19.  
  20. #include "/common/types.h"
  21. #include "/common/defines.h"
  22. #include "/common/structures.h"
  23. #include "/common/strings.h"
  24. #include "/common/errors.h"
  25. #include "/common/shared_protos.h"
  26. #include "/common/Files.h"
  27.  
  28. #include "Node_Input_protos.h"
  29. #include "Node_Console_protos.h"
  30. #include "/library/hbbscommon_protos.h"
  31. #include "/library/hbbscommon_pragmas.h"
  32. #include "nodelibrary/hbbsnode_protos.h"
  33. #include "nodelibrary/hbbsnode_pragmas.h"
  34.  
  35. extern struct NodeData *N_ND;
  36. extern struct BBSGlobalData *BBSGlobal;
  37. extern struct Library *HBBSCommonBase;
  38. extern struct Library *HBBSNodeBase;
  39.  
  40.  
  41. void CleanupSerial( void )
  42. {
  43.   if (!N_ND->NodeDevice.SysopNode)
  44.   {
  45.     if (N_ND->SerBuffer)
  46.     {
  47.       if (N_ND->SerPort)
  48.       {
  49.         if (N_ND->SerWrite)
  50.         {
  51.           if (N_ND->SerOPEN)
  52.           {
  53.             if (N_ND->SerRead)
  54.             {
  55.               AbortSerRead(); // will only abort id request submitted..
  56.               FreeVec(N_ND->SerRead);
  57.             }
  58.             CloseDevice((struct IORequest*)N_ND->SerWrite);
  59.             N_ND->SerOPEN=FALSE;
  60.           }
  61.           DeleteExtIO((struct IORequest*)N_ND->SerWrite);
  62.         }
  63.         DeletePort(N_ND->SerPort);
  64.       }
  65.       FreeVec(N_ND->SerBuffer);
  66.     }
  67.   }
  68.   N_ND->SerOK=FALSE;
  69. }
  70.  
  71. void SerReset( void )
  72. {
  73.   // this routine reads in all waiting data from the serial port and then dumps it!
  74.   UBYTE *mem;
  75.   ULONG bytes;
  76.  
  77.   if (bytes=SerQueryData())
  78.   {
  79.     if (mem=AllocVec(bytes,MEMF_PUBLIC))
  80.     {
  81.       WaitSerReadBlock(mem,bytes); // *C* ooh naughty.. should really have somekind of wait() here..
  82.       FreeVec(mem);
  83.     }
  84.   }
  85. }
  86.  
  87. V_BOOL OpenSerial( void )
  88. {
  89.   N_ND->SerWaiting=FALSE;
  90.   N_ND->SerOK=FALSE;
  91.   N_ND->SerOPEN=FALSE;
  92.   if (!N_ND->NodeDevice.SysopNode)
  93.   {
  94.     if (N_ND->SerBuffer=AllocVec(DEF_SERBUFLEN,MEMF_PUBLIC))
  95.     {
  96.       N_ND->SerBufferLen=DEF_SERBUFLEN;
  97.       if (N_ND->SerPort=CreatePort(0,0))
  98.       {
  99.         if (N_ND->SerWrite = (struct IOExtSer *) CreateExtIO(N_ND->SerPort,(ULONG)sizeof(struct IOExtSer)))
  100.         {
  101.           if (N_ND->NodeDevice.NullModemCable)
  102.           {
  103.             N_ND->SerWrite->io_SerFlags       = SERF_SHARED;
  104.           }
  105.           else
  106.           {
  107.             N_ND->SerWrite->io_SerFlags       = SERF_SHARED|SERF_7WIRE|SERF_XDISABLED|SERF_RAD_BOOGIE;
  108.           }
  109.           if (!(OpenDevice((STRPTR)N_ND->NodeDevice.SerialDevice,(ULONG)N_ND->NodeDevice.SerialUnit,(struct IORequest *)N_ND->SerWrite,0L) ))
  110.           {
  111.             N_ND->SerOPEN=TRUE;
  112.             // kill data waiting..
  113.             N_ND->SerWrite->IOSer.io_Command  = CMD_RESET;
  114.             DoIO((struct IORequest *)N_ND->SerWrite);
  115.  
  116.  
  117.             // setup port with correct baud rate etc..
  118.             N_ND->SerWrite->IOSer.io_Command  = SDCMD_SETPARAMS;
  119.             N_ND->SerWrite->io_SerFlags       |= SERF_XDISABLED;
  120.             N_ND->SerWrite->io_Baud           = N_ND->NodeDevice.SerialBaud;
  121.             DoIO((struct IORequest *)N_ND->SerWrite);
  122.  
  123.  
  124.             if (N_ND->SerRead = (struct IOExtSer*)AllocVec(sizeof(struct IOExtSer),MEMF_PUBLIC) )
  125.             {
  126.               // duplicate data...
  127.               memcpy(N_ND->SerRead,N_ND->SerWrite,sizeof(struct IOExtSer));
  128.               SerReset();
  129.               N_ND->SerOK=TRUE;
  130.               return(TRUE);
  131.             }
  132.           }
  133.           else HBBS_DoErrorMessage(EMSG_NODEVICE,N_ND->NodeNum,NULL);
  134.         }
  135.       }
  136.     }
  137.     CleanupSerial();
  138.   }
  139.   return(FALSE);
  140. }
  141.  
  142. ULONG ModemGetLine( void )
  143. {
  144.   ULONG ReturnedSigs;
  145.   UBYTE CurrentChar[2]={0,0}; // 2 chars, use ¤tchar for null terminated string type..
  146.   ULONG retval=IN_NOTHING; // this must NOT be returned to the caller!!!!!
  147.  
  148.   struct TimerData *TD;
  149.  
  150.   N_ND->CurrentLine[0]=0; // null terminate the string..
  151.  
  152.   if (TD=SubmitTimer(N_ND->NodeTimer,N_ND->NodeDevice.MaxCommandWait,0))
  153.   {
  154.     do
  155.     {
  156.       if (!N_ND->SerWaiting) SendSerReadData();
  157.  
  158.       // we cant use SetupSigs() and WaitAllSigs() because if we are resetting
  159.       // the modem after a LOGIN_LOCAL sersigs is set to 0... :-)
  160.       // *C* add timeout
  161.       N_ND->SerSig=DEF_SERSIG;
  162.       N_ND->TimerSig=DEF_TIMERSIG;
  163.       ReturnedSigs=Wait(N_ND->SerSig | N_ND->TimerSig);
  164.  
  165.       while (HandleSerSigs(ReturnedSigs) && retval==IN_NOTHING)
  166.       {
  167.         // ok, we got some data from somehwere...
  168.  
  169.         CurrentChar[0]=N_ND->IBuffer[0];
  170.  
  171.         if (CurrentChar[0]>=0x20 && CurrentChar[0]!=127) // i.e. not unprintable or a control char..
  172.         {
  173.           strcat(N_ND->CurrentLine,CurrentChar);
  174.         }
  175.         else
  176.         {
  177.           if (CurrentChar[0]=='\n')
  178.           {
  179.             if (strlen(N_ND->CurrentLine)>0) retval=IN_GOTLINE;
  180.           }
  181.         }
  182.       }
  183.  
  184.       if ((retval==IN_NOTHING) && (CheckTimer(N_ND->NodeTimer,TD)))
  185.       {
  186.         TD=NULL;
  187.         retval=IN_TIMEOUT;
  188.       }
  189.     }
  190.     while (retval==IN_NOTHING);
  191.     if (TD) AbortTimer(N_ND->NodeTimer,TD);
  192.  
  193.     if (N_ND->NodeDevice.ModemDebug && N_ND->ConOK)
  194.     {
  195.       ConWriteStr(N_ND->CurrentLine);
  196.       ConWriteStr(str_CRLF);
  197.     }
  198.     if (N_ND->SerWaiting) AbortSerRead();
  199.   }
  200.   return(retval);
  201. }
  202.  
  203. void ModemError(char *command, char *result)
  204. {
  205.   char errstr[2048]; // big enough ?
  206.  
  207.   if (N_ND->NodeDevice.ModemLog)
  208.   {
  209.     sprintf(errstr,"When Sending the command \"%s\" the modem returned \"%s\"",command,result);
  210.  
  211.     HBBS_LogError(N_ND->NodeSettings.ModemLogFile,ERR_GENERAL,errstr,TYPE_WARNING);
  212.   }
  213. }
  214.  
  215. void TurnEchoOn( void )
  216. {
  217.   struct Node *node;
  218.   short retriesleft;
  219.   BOOL Done;
  220.   ULONG result;
  221.  
  222.  
  223.   PutText("\033[37;0m\n");
  224.   for (node=N_ND->NodeDevice.TurnOnEcho->lh_Head;node->ln_Succ;node=node->ln_Succ)
  225.   {
  226.     if (node->ln_Name)
  227.     {
  228.       Done=FALSE;
  229.       retriesleft=N_ND->NodeDevice.EchoRetries;
  230.       do
  231.       {
  232.         if (retriesleft!=N_ND->NodeDevice.EchoRetries)
  233.         {
  234.           ConWriteStr("Retrying Modem...\n\r");
  235.         }
  236.  
  237.         retriesleft--;
  238.         Delay(N_ND->NodeDevice.TurnOnEchoDelay);
  239.         SerReset();
  240.         SerWriteStr(node->ln_Name);
  241.         SerWriteStr(str_CRLF);
  242.         if (result=ModemGetLine()==IN_GOTLINE)
  243.         {
  244.           // ok, got some input..
  245.  
  246.           if (stricmp(node->ln_Name,N_ND->CurrentLine)==0)
  247.           {  // echo is already on, so discard this line and read another line..
  248.             result=ModemGetLine();
  249.           }
  250.           if (result==IN_GOTLINE)
  251.           {
  252.             if (stricmp("OK",N_ND->CurrentLine)==0) Done=TRUE;
  253.           }
  254.         }
  255.       } while (!Done && retriesleft>0);
  256.     }
  257.   }
  258.   SerReset();
  259. }
  260.  
  261. V_BOOL SendModemString(char *str)
  262. {
  263.   ULONG err=1;
  264.   ULONG loop,loop2=N_ND->NodeDevice.CommandRetries;
  265.   BOOL linemismatch;
  266.  
  267.   do
  268.   {
  269.  
  270.     // this loop sends the command to the modem and wait for the characters to
  271.     // be echoed back.  if we don't get back what we send we try it again!
  272.  
  273.     loop=N_ND->NodeDevice.CommandRetries;
  274.     do
  275.     {
  276.       Delay(N_ND->NodeDevice.DelayBetweenCmds);
  277.       SerReset(); //clear all crap before we send our new string..
  278.       SerWriteStr(str);
  279.       SerWriteStr(str_CRLF);
  280.       ModemGetLine();
  281.       if (linemismatch=(stricmp(str,N_ND->CurrentLine)!=0 ? TRUE : FALSE))
  282.       {
  283.         TurnEchoOn();
  284.       }
  285.     } while (loop-- && linemismatch);
  286.  
  287.     // right if we are here then we know we're gonna get a blank line and a timeout
  288.     // or OK OR ERROR..  if we don't get OK then we retry the command...
  289.     ModemGetLine();
  290.  
  291.   } while (loop2-- && stricmp(N_ND->CurrentLine,"OK")!=0 && (err=stricmp(N_ND->CurrentLine,"ERROR"))==0);
  292.   if (!err) ModemError(str,N_ND->CurrentLine);
  293.   return(err);
  294. }
  295.  
  296. void OffHook( void )
  297. {
  298.   SendModemString(N_ND->NodeDevice.OffHookString);
  299. }
  300.  
  301. void ReOpenSerial( void )
  302. {
  303.   V_SMALLNUM loop=N_ND->NodeDevice.ReOpenRetries;
  304.   if (!N_ND->NodeDevice.SysopNode)
  305.   {
  306.     CleanupSerial();
  307.  
  308.     while (loop-- && N_ND->SerOK==FALSE)
  309.     {
  310.       Delay(N_ND->NodeDevice.ReOpenDelay);
  311.       OpenSerial();
  312.     }
  313.  
  314.     if (!N_ND->SerOK)
  315.     {
  316.       HBBS_LogError(BBSGlobal->ErrorLogFile,ERR_GENERAL,ESTR_NOSERIAL,TYPE_CRITICAL);
  317.     }
  318.   }
  319. }
  320.  
  321. void HangUp( void )
  322. {
  323.   struct Node *node;
  324.  
  325.   if (!N_ND->NodeDevice.NullModemCable)
  326.   {
  327.     if (!N_ND->NodeDevice.DropDTRHangup)
  328.     {
  329.       for (node=N_ND->NodeDevice.CommandModeString->lh_Head;node->ln_Succ;node=node->ln_Succ)
  330.       {
  331.         if (node->ln_Name) SerWriteStr(node->ln_Name);
  332.       }
  333.       SendModemString(N_ND->NodeDevice.HangUpString);
  334.     }
  335.     ReOpenSerial();
  336.     OffHook();
  337.   }
  338.   else
  339.   {
  340.     ReOpenSerial();
  341.   }
  342. }
  343.  
  344. V_BOOL InitModem( void )
  345. {
  346.   struct Node *node;
  347.  
  348.   if (N_ND->NodeDevice.ModemDebug && N_ND->ConOK)
  349.   {
  350.     ConWriteStr("Initialising Modem...\n\r");
  351.   }
  352.  
  353.   TurnEchoOn();
  354.   for (node=N_ND->NodeDevice.ModemInit->lh_Head;node->ln_Succ;node=node->ln_Succ)
  355.   {
  356.     if (node->ln_Name) SendModemString(node->ln_Name);
  357.   }
  358.   return(TRUE);
  359. }
  360.  
  361.